package se.webbzon.boltzmann.player;

import java.awt.Point;

import se.webbzon.boltzmann.inventory.Inventory;
import se.webbzon.boltzmann.inventory.InventoryListener;
import se.webbzon.boltzmann.inventory.Inventory.Size;
import se.webbzon.boltzmann.item.AbstractItem;

public class PlayerModel {
	
	// The inventory of the player
	private final Inventory inventory;

	// The health, energy and coins of the player
	private final PlayerHealth health;
	private final PlayerEnergy energy;
	private final PlayerCoins coins;
	private final PlayerLevel level;

	// The current location of the player
	private final PlayerLocation location;

	// The current character used by the player
	private PlayerCharacter character;

	// The selected item
	private AbstractItem selectedItem;
	
	/*============================================================
	Constructors
	============================================================*/
	
	public PlayerModel() {
		inventory = new Inventory(Inventory.Size.SMALL);
		health = new PlayerHealth();
		energy = new PlayerEnergy();
		coins = new PlayerCoins();
		location = new PlayerLocation();
		level = new PlayerLevel();
		
		character = BoltzmannCharacter.instance();
		selectedItem = null;
		inventory.addListener(new InventoryListenerImpl());
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Returns the inventory for this player. **/
	public Inventory getInventory() {
		return inventory;
	}
	
	/** Returns the current character used by the player. **/
	public PlayerCharacter getCharacter() {
		return character;
	}
	
	/** Sets the current character used by the player. **/
	public void setCharacter(PlayerCharacter character) {
		this.character = character;
	}
	
	/** Returns the current location of the player. **/
	public PlayerLocation getLocation() {
		return location;
	}
	
	/** Returns the health of this player. **/
	public PlayerHealth getHealth() {
		return health;
	}
	
	/** Returns the energy of this player. **/
	public PlayerEnergy getEnergy() {
		return energy;
	}
	
	/** Returns the coins of this player. **/
	public PlayerCoins getCoins() {
		return coins;
	}
	
	/** Returns the selected item for this player. If null is returned then
	 * no item is selected. **/
	public AbstractItem getSelectedItem() {
		return selectedItem;
	}
	
	/** Sets the selected item for this player. **/
	public void setSelectedItem(AbstractItem selectedItem) {
		// Check if the item exists in the inventory
		if (inventory.getPosition(selectedItem, new Point()))
			this.selectedItem = selectedItem;
	}
	
	/** Returns the level of the player. **/
	public PlayerLevel getLevel() {
		return level;
	}
	
	/** Copies the properties from the given player into this player. **/
	public void copyFrom(PlayerModel player) {
		health.setMaxHealth(player.getHealth().getMaxHealth());
		health.setHealth(player.getHealth().getHealth());
		energy.setMaxEnergy(player.getEnergy().getMaxEnergy());
		energy.setEnergy(player.getEnergy().getEnergy());
		coins.setMaxCoins(player.getCoins().getMaxCoins());
		coins.setCoins(player.getCoins().getCoins());
		level.setLevel(player.getLevel().getLevel());
		level.setNotes(player.getLevel().getNotes());
		inventory.copyFrom(player.getInventory());
		location.setRegion(player.getLocation().getRegion());
		location.setWorldAreaName(player.getLocation().getWorldAreaName());
		location.setPortalId(player.getLocation().getPortalId());
		Point p = new Point();
		if (player.inventory.getPosition(player.selectedItem, p)) {
			selectedItem = inventory.getItem(p.x, p.y);
		}
		character = player.getCharacter();
	}
	
	/*============================================================
	Private Classes
	============================================================*/
	
	private final class InventoryListenerImpl implements InventoryListener {

		@Override public void itemAdded(Inventory inventory, AbstractItem item) {
			if (selectedItem == null)
				selectedItem = item;
		}

		@Override public void itemRemoved(Inventory inventory, AbstractItem item) {
			if (selectedItem == item) {
				if (inventory.getNumberOfItems() == 1)
					selectedItem = null;
				else {
					Point predecessor = new Point();
					inventory.getPredecessor(selectedItem, predecessor);
					selectedItem = 
							inventory.getItem(predecessor.x, predecessor.y);
				}
			}
		}

		@Override public void itemSwapped(Inventory inventory, AbstractItem item1, AbstractItem item2) {};

		@Override public void inventoryResized(Inventory inventory, Size size) {};
		
	}

}
